package cn.com.chengmandian.agent.utils;

import cn.com.chengmandian.core.common.constants.CommonConstant;
import cn.com.chengmandian.core.common.enums.ClientsEnum;
import cn.com.chengmandian.core.redis.cache.CacheHelper;
import cn.com.chengmandian.core.redis.service.RedisService;
import cn.com.chengmandian.core.web.pojo.AgentInfo;
import cn.com.chengmandian.core.web.pojo.AgentUser;
import cn.com.chengmandian.core.web.utils.LocalMapUtil;
import cn.com.chengmandian.core.web.utils.SpringContextUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONUtil;
import cn.hutool.jwt.JWT;
import cn.hutool.jwt.JWTUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;
import javax.servlet.http.HttpServletRequest;

@Slf4j
@Component
public class AuthUtil {

    @Autowired
    private RedisService redisService;

    private static RedisService SRedisService;

    @PostConstruct
    public void init() {
        AuthUtil.SRedisService = redisService;
    }

    // 缓存用户token，用于防止重复登陆
    public static void putTenant(AgentUser agentUser, String secret, String token, Integer expireDay) {
        String key = CacheHelper.buildKey("CMD:WEB:AGENT:TOKEN:" + secret + ":", agentUser.getId() + "");
        SRedisService.set(key, token, expireDay * 24 * 60 * 60);
    }

    // 缓存用户token，用于防止重复登陆
    public static void removeTenant(Integer userId, String secret, String token, Integer expireDay) {
        String key = CacheHelper.buildKey("CMD:WEB:AGENT:TOKEN:" + secret + ":", userId + "");
        SRedisService.set(key, token, expireDay * 24 * 60 * 60);
    }

    // 检查用户是否重复登陆(20240709存在问题，没有区分用户类型)
    public static Boolean checkTenant(ClientsEnum client, AgentUser agentUser, HttpServletRequest request, String secret) {
        String key = CacheHelper.buildKey("CMD:WEB:AGENT:TOKEN:" + secret + ":", agentUser.getId() + "");
        Object value = SRedisService.get(key);
        if (value == null || StrUtil.isEmpty(value.toString())) {
            return false;
        }
        String token = request.getHeader(client.getHeaderName());
        if (StrUtil.isEmpty(token) || !token.equals(value)) {
            return false;
        }
        return true;
    }

    /**
     * 获取用户信息
     */
    public static AgentUser getAgentUser(String token, AgentInfo agentInfo) {
        try {
            if (!JWTUtil.verify(token, agentInfo.getTokenSecret().getBytes())) {
                if (SpringContextUtil.isDev()) {
                    log.error("Token验证未通过：{}", token);
                }
                return null;
            }
        } catch (Exception e) {
            log.error("Token验证出错：{}", token);
            return null;
        }
        JWT jwt = JWTUtil.parseToken(token);
        AgentUser agentUser = jwt.getPayloads().toBean(AgentUser.class);
        if (agentUser == null) return null;
        if (SpringContextUtil.isDev()) {
            log.info("Token：{}", JSONUtil.toJsonStr(agentUser));
        }

        if (agentUser.getExpireDate() < DateUtil.date().getTime()) {
            log.info("Token已过期：{}", token);
            return null;
        }
        return agentUser;
    }

    public static AgentUser getAgentUser(HttpServletRequest request, ClientsEnum client, AgentInfo agentInfo) {
        String token = request.getHeader(client.getHeaderName());
        if (StrUtil.isBlank(token)) return null;
        return getAgentUser(request.getHeader(client.getHeaderName()), agentInfo);
    }

    /**
     * 获取当前登陆用户
     * @return
     */
    public static AgentUser getAgentUser() {
        HttpServletRequest request = ServletUtil.getRequest();
        if (request == null) return null;
        AgentInfo agentInfo = LocalMapUtil.getAgentInfo();
        if (agentInfo == null) return null;
        String clientId = request.getHeader(CommonConstant.HEADER_CLIENT_ID);
        if (StrUtil.isBlank(clientId)) return null;
        ClientsEnum client = ClientsEnum.codeOf(clientId);
        if (client == null) return null;
        return getAgentUser(request, client, agentInfo);
    }

    public static <T> T get(String key) {
        AgentUser user = getAgentUser();
        if (user.getAttrs() == null || !user.getAttrs().containsKey(key)) return null;
        return (T)user.getAttrs().get(key);
    }
}
